import 'dart:convert';
import 'dart:async';
import 'package:http/http.dart' show Client;
import 'models/OverViewModel.dart';
import 'models/detail_model.dart';
import 'package:convert/convert.dart';
import 'package:crypto/crypto.dart';
import 'package:device_info/device_info.dart';
import 'dart:typed_data';
import 'package:encrypt/encrypt.dart';
import 'models/rank_model.dart';
import 'models/detail_list.dart';

///域名 服务路径
//const baseUrl = 'http://192.168.50.54:8080'; //本地
const baseUrl = 'https://app.88jlu.com'; //线上
//预览path
const overViewPath = '/api/bi/getDataOverview';
//平台列表
const platInfoPath = '/api/bi/listDomain';
//单平台详情
const singleDetailPath = '/api/bi/getDomainDetail';
//所有平台详情
const allDetailPath = '/api/bi/getDataList';
//数据排名
const rankPath = '/api/bi/getPlatfromDataTop';



//AES解密私钥
const privateKey = 'wgdata!@#!!23133';
//请求秘钥
const requestKey = 'wgdataprivatekey';

class OverViewProvider {
  Client client = Client();
  static Future<String> getDeviceNo() async {
    DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
    final iosInfo = await deviceInfo.iosInfo;
    final deviceId = iosInfo.identifierForVendor;
    return deviceId;
  }
  ///AES解密
  static Future<String> decrypt(String keyStr, String data) async{
    //返回数据带引号，截取引号
    var rData = data.substring(1,data.length-1);
    final key = Uint8List.fromList(privateKey.codeUnits);
    final sKey = Key(key);
    final encrypter = Encrypter(AES(sKey, mode: AESMode.ecb, padding: 'PKCS7'));
    final String decrypted = encrypter.decrypt64(rData);
    return decrypted;
  }
  ///数据总览
  //getDataOverview
  //加密参数 sign:MD5(order+dateType+deviceNo+wgdataprivatekey) order 可为空
  Future<OverViewModel> fetchOverView(order,dateType) async {
    final deviceId = await getDeviceNo();
    var content = '${order}${dateType}${deviceId}${requestKey}';
    if(order == null) {
      content = '${dateType}${deviceId}${requestKey}';
    }
    final md5String = md5.convert(Utf8Encoder().convert(content));
    final sign = hex.encode(md5String.bytes);
    var urlString;
    if(order == null){
      urlString = '${baseUrl}${overViewPath}?dateType=${dateType}&deviceNo=${deviceId}&sign=${sign}';
    } else {
      urlString = '${baseUrl}${overViewPath}?dateType=${dateType}&order=${order}&deviceNo=${deviceId}&sign=${sign}';
    }
    print(urlString);
    final response = await client
        .get(urlString);
    if(response.statusCode == 200) {
      final resString = response.body;
      print(resString);
      final rData = await decrypt(privateKey, resString);
      print(rData);
      return OverViewModel.fromJson(json.decode(rData));
    } else {
      throw Exception('数据错误');
    }
  }
  //平台详情
  //getDomainDetail
  //加密参数 sign:MD5(dateType+domain+deviceNo+wgdataprivatekey)
  Future<SinglePlatDetailModel> fetchPlatDetail(dateType,domain) async {
    final deviceId = await getDeviceNo();
    print("*************************");
    print(deviceId);
    var content = '${dateType}${domain}${deviceId}${requestKey}';
    final md5String = md5.convert(Utf8Encoder().convert(content));
    final sign = hex.encode(md5String.bytes);
    final urlString = '${baseUrl}${singleDetailPath}?dateType=${dateType}&domain=${domain}&deviceNo=${deviceId}&sign=${sign}';
    print(urlString);
    final response = await client
        .get(urlString);
    if(response.statusCode == 200) {
      print(response.body);
      final rData = await decrypt(privateKey, response.body);
      print(json.decode(rData));
      return SinglePlatDetailModel.fromJson(json.decode(rData));
    } else {
      throw Exception('Failed to load post');
    }
  }

  //getDataList
  //加密参数 sign:MD5(dateType+deviceNo+wgdataprivatekey)
  //dateType equit to 0 => MD5(dateType+deviceNo+startDate+endDate+wgdataprivatekey)
  Future<DetailListModel> fetchDetailList(dataType, startDate, endDate) async {
    print('dateType:${dataType} startDate:${startDate} endDate:${endDate}');
    final deviceId = await getDeviceNo();
    print("*************************");
    print(deviceId);
    var content = '';
    if(dataType == 0) {
      content = '${dataType}${deviceId}${startDate}${endDate}${requestKey}';
    } else {
      content = '${dataType}${deviceId}${requestKey}';
    }
    final md5String = md5.convert(Utf8Encoder().convert(content));
    final sign = hex.encode(md5String.bytes);
    var urlString = '';
    if(dataType == 0) {
      urlString = '${baseUrl}${allDetailPath}?deviceNo=${deviceId}&startDate=${startDate}&endDate=${endDate}&dateType=${dataType}&sign=${sign}';
    } else {
      urlString = '${baseUrl}${allDetailPath}?deviceNo=${deviceId}&dateType=${dataType}&sign=${sign}';
    }

    print(urlString);
    final response = await client.get(urlString);
    if(response.statusCode == 200) {
      final rData = await decrypt(privateKey, response.body);
      print(rData);
      return DetailListModel.fromJson(json.decode(rData));
    } else {
      throw Exception('Fail to get data');
    }
  }
  //listDomain
  //加密参数 sign:MD5(deviceNo+wgdataprivatekey)
  Future<List<PlatInfoData>> fetchPlatList() async {
    final deviceId = await getDeviceNo();
    print("*************************");
    print(deviceId);
    var content = '${deviceId}${requestKey}';
    final md5String = md5.convert(Utf8Encoder().convert(content));
    final sign = hex.encode(md5String.bytes);
    final urlString = '${baseUrl}${platInfoPath}?deviceNo=${deviceId}&sign=${sign}';
    print(urlString);
    final response = await client
        .get(urlString);
    if(response.statusCode == 200) {
      final rData = await decrypt(privateKey, response.body);
      List<dynamic> allPlat = json.decode(rData);
      List<PlatInfoData> allData = allPlat.map((e) => PlatInfoData.fromJson(e)).toList();
      return allData;
    } else {
      throw Exception('Failed to load post');
    }
  }
  //getPlatfromDataTop
  //加密参数 sign:MD5(order+dateType+deviceNo+topType+wgdataprivatekey)
  //排名统计/
  Future<RankDataModel> fetchRankData(order,dateType, topType) async {
    final deviceId = await getDeviceNo();
    print("*************************");
    print(deviceId);
    var content = '${order}${dateType}${deviceId}${topType}${requestKey}';
    if(order == null) {
      content = '${dateType}${deviceId}${topType}${requestKey}';
    }
    final md5String = md5.convert(Utf8Encoder().convert(content));
    final sign = hex.encode(md5String.bytes);
    var  urlString = '${baseUrl}${rankPath}?order=${order}&topType=${topType}&dateType=${dateType}&deviceNo=${deviceId}&sign=${sign}';
    if(order == null) {
      urlString = '${baseUrl}${rankPath}?topType=${topType}&dateType=${dateType}&deviceNo=${deviceId}&sign=${sign}';
    }
    print(urlString);
    final response = await client
        .get(urlString);
    if(response.statusCode == 200) {
      final rData = await decrypt(privateKey, response.body);
      return RankDataModel.fromJson(json.decode(rData));
    } else {
      throw Exception('Failed to load post');
    }
  }
}

